⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccomm.cpp

📁 这是G.723和G.729的音频编解码的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include "stdafx.h"
#include <afxmt.h>
#include "CPacker.h"
#include <afxtempl.h>
#include "CChannel.h"
#include "CMultiplex.h"
#include "CDemultiplex.h"
#include "CByteBuffer.h"
#include "CComm.h"

CComm::CComm(CommCallBackFunc pCallBackFunc,
			 CMultiplex * pMultiplex,
			 CDemultiplex * pDemultiplex,
			 int nBaudRate,
			 int nInputBufferSize,
			
			 int nOutputBufferSize,
			 BOOL bDisplayError):m_InputBuffer(READ_BUFFER_SIZE)
{
	m_pMultiplex=pMultiplex;
	m_pDemultiplex=pDemultiplex;
	m_hComm=NULL;
	ZeroMemory(&m_WriteOS,sizeof(OVERLAPPED));
	ZeroMemory(&m_ReadOS,sizeof(OVERLAPPED));;
	m_nPort=0;
	m_bConnected=FALSE;
	m_bDisplayError=bDisplayError;
	m_nBaudRate=nBaudRate;
	m_nInputBufferSize=nInputBufferSize;
	m_nOutputBufferSize=nOutputBufferSize;

	m_dwThreadID=0;
	m_hThread=NULL;
	
	m_dwWriteThreadID=0;
	m_hWriteThread=NULL;

	m_dwReadThreadID=0;
	m_hReadThread=NULL;

	m_pCallBackFunc=pCallBackFunc;
	m_lpUserInstance=NULL;

	m_uBlockSize=m_nOutputBufferSize/2;
	if(m_uBlockSize>4096)
		m_uBlockSize=4096;	

	m_uMiniBlockSize=100;
	if(m_uMiniBlockSize>m_uBlockSize/2)
		m_uMiniBlockSize=0;

	m_hQuitEvent=NULL;
	m_hWriteEvent=NULL;
	m_hCTSEvent=NULL;
	m_hReadEvent=NULL;
}

BOOL CComm::OpenComm(int nPortNumber,LPVOID lpUserInstance)
{	
	if(m_bConnected)return FALSE;

	m_lpUserInstance=lpUserInstance;
	m_nPort=nPortNumber;

	if(!CreateTTYInfo())return FALSE;
	m_hQuitEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,TRUE,FALSE,NULL);
	if(!m_hQuitEvent)return FALSE;

	m_hWriteEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,FALSE,TRUE,NULL);
	if(!m_hWriteEvent)
	{
		CloseHandle(m_hQuitEvent);
		m_hQuitEvent=0;
		return FALSE;
	}

	m_hReadEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,FALSE,FALSE,NULL);
	if(!m_hReadEvent)
	{
		CloseHandle(m_hWriteEvent);
		CloseHandle(m_hQuitEvent);
		m_hWriteEvent=0;
		m_hQuitEvent=0;
		return FALSE;
	}

	m_hCTSEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,FALSE,FALSE,NULL);
	if(!m_hCTSEvent)
	{
		CloseHandle(m_hWriteEvent);
		CloseHandle(m_hQuitEvent);
		CloseHandle(m_hReadEvent);
		m_hWriteEvent=0;
		m_hQuitEvent=0;
		m_hReadEvent=0;
		return FALSE;
	}

	if(!OpenConnection())
	{
		CloseHandle(m_hWriteEvent);
		CloseHandle(m_hQuitEvent);
		CloseHandle(m_hReadEvent);
		CloseHandle(m_hCTSEvent);
		m_hWriteEvent=0;
		m_hQuitEvent=0;
		m_hReadEvent=0;
		m_hCTSEvent=0;
		return FALSE;
	}
	return TRUE;
}

BOOL CComm::CreateTTYInfo()
{
   m_WriteOS.Offset = 0 ;
   m_WriteOS.OffsetHigh = 0 ;
   m_ReadOS.Offset = 0 ;
   m_ReadOS.OffsetHigh = 0 ;

   // create I/O event used for overlapped reads / writes
   m_ReadOS.hEvent = CreateEvent( NULL,    // no security
                                              TRUE,    // explicit reset req
                                              FALSE,   // initial event reset
                                              NULL ) ; // no name
   if (m_ReadOS.hEvent == NULL)         
      return FALSE;
   

   m_WriteOS.hEvent = CreateEvent( NULL,    // no security
                                               TRUE,    // explicit reset req
                                               FALSE,   // initial event reset
                                               NULL ) ; // no name
   if (NULL == m_WriteOS.hEvent)
   {
      CloseHandle(m_ReadOS.hEvent ) ;      
      return FALSE;
   }
   return TRUE;

} // end of CreateTTYInfo()

DWORD FAR PASCAL ReadThreadProc(CComm* pCommObject)
{
	CComm* pComm=(CComm*)pCommObject;		
	HANDLE phWaitObjects[2]={pComm->m_hQuitEvent,pComm->m_hReadEvent};
	DWORD dwEvtMask=0;
	int nRequireLength=256;
	BYTE  abIn[1024] ;
	int   nLength ;

	while(1)
	{
		dwEvtMask=WaitForMultipleObjects(2,phWaitObjects,FALSE,INFINITE);

		if(dwEvtMask==WAIT_OBJECT_0)
			break;

		if(dwEvtMask==WAIT_OBJECT_0+1)
		{
		/*	do
		   {
				if (nLength = (pComm->ReadCommBlock((LPSTR) abIn, MAXBLOCK )))
				{					
					if(pComm->m_pCallBackFunc)
						(*(pComm->m_pCallBackFunc))(abIn,nLength,pComm->m_lpUserInstance);
		      	}
		   }
		   while ( nLength > 0 ) ;
		*/
			do
		   {
				if (nLength=pComm->m_InputBuffer.DetachHeader(abIn,nRequireLength))
				{					
					if(pComm->m_pCallBackFunc)
						(*(pComm->m_pCallBackFunc))(abIn,nLength,pComm->m_lpUserInstance);
		      	}
		   }
		   while ( nLength > 0 ) ;
		   continue;
		}
		if(dwEvtMask==WAIT_TIMEOUT)		
			continue;		
	}
	pComm->m_hReadThread=0;
	pComm->m_dwReadThreadID=0;
	return 0;
}

DWORD FAR PASCAL WriteThreadProc(CComm* pCommObject)
{	
	DWORD dwEvtMask=0;	
	CComm* pComm=(CComm*)pCommObject;
	BYTE pbyTransferBlock[4096];
	int nStreamLength;
	HANDLE phWaitObjects[3]={
							  pComm->m_hQuitEvent,
							  pComm->m_hWriteEvent,
							  pComm->m_hCTSEvent
							 };	
	while(1)
	{
		
		dwEvtMask=WaitForMultipleObjects(3,phWaitObjects,FALSE,25);
		if(dwEvtMask==WAIT_OBJECT_0)
			break;
		if(dwEvtMask==WAIT_OBJECT_0+1)
		{	
			while(1)
			{
				int nStreamLength=pComm->m_pMultiplex->DetachStream(pbyTransferBlock,256);
				if(nStreamLength)
				{
					pComm->WriteCommBlock(pbyTransferBlock,nStreamLength);
					break;			
				}
				if(WAIT_OBJECT_0==WaitForSingleObject(pComm->m_hQuitEvent,50))
					goto END;
			}
			
		}
		if(dwEvtMask==WAIT_OBJECT_0+2)
		{
			static bFull;
			bFull=!bFull;
		}

		if(dwEvtMask==WAIT_TIMEOUT)
		{			
			nStreamLength=pComm->m_pMultiplex->DetachStream(pbyTransferBlock,128);
			if(nStreamLength)
			{
				pComm->WriteCommBlock(pbyTransferBlock,nStreamLength);
			}			
		}
	}
END:
	pComm->m_hWriteThread=NULL;
	pComm->m_dwWriteThreadID=0;
	return 0;
}

DWORD FAR PASCAL CommWatchProc(CComm* pCommObject)
{
   DWORD       dwEvtMask ;
   CComm*   pComm= (CComm*)pCommObject;
   OVERLAPPED  os ;

   int        nLength ;
   BYTE       abIn[ MAXBLOCK + 1] ;
   
   memset( &os, 0, sizeof( OVERLAPPED ) ) ;

   // create I/O event used for overlapped read

   os.hEvent = CreateEvent( NULL,    // no security
                            TRUE,    // explicit reset req
                            FALSE,   // initial event reset
                            NULL ) ; // no name
   if (os.hEvent == NULL)
   {
      MessageBox( NULL, "Failed to create event for thread!", "TTY Error!",
                  MB_ICONEXCLAMATION | MB_OK ) ;
      return ( FALSE ) ;
   }

   if (!SetCommMask(pComm->m_hComm, EV_RXCHAR|EV_RLSD|EV_TXEMPTY|EV_CTS))
      return ( FALSE ) ;

   while (pComm->m_bConnected)
   {
		dwEvtMask = 0 ;

		WaitCommEvent(pComm->m_hComm, &dwEvtMask, NULL );

		
		if ((dwEvtMask & EV_RLSD) == EV_RLSD)
		{
			if(pComm->m_pCallBackFunc)
				(*(pComm->m_pCallBackFunc))(NULL,0xffffffff,pComm->m_lpUserInstance);
		}

		if((dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY)
		{
			SetEvent(pComm->m_hWriteEvent);
		}

		if((dwEvtMask & EV_CTS) == EV_CTS)
		{
			SetEvent(pComm->m_hCTSEvent);
		}

		if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
		{/*
			do
		   {
				if (nLength = (pComm->ReadCommBlock((LPSTR) abIn, MAXBLOCK )))
				{
					if(pComm->m_pCallBackFunc)
						(*(pComm->m_pCallBackFunc))(abIn,nLength,pComm->m_lpUserInstance);				
		      	}
		   }
		   while ( nLength > 0 ) ;
		  */
		    do
		   {
				if (nLength = (pComm->ReadCommBlock((LPSTR) abIn, MAXBLOCK )))
					pComm->m_InputBuffer.AppendTail(abIn,nLength);		      	
		   }
		   while ( nLength > 0 ) ;		   
		   SetEvent(pComm->m_hReadEvent);
		}
   }

   // get rid of event handle

   CloseHandle( os.hEvent ) ;

   // clear information in structure (kind of a "we're done flag")

   pComm->m_dwThreadID = 0 ;
   pComm->m_hThread = NULL ;

   return( TRUE ) ;

} // end of CommWatchProc()

int CComm::ReadCommBlock(LPSTR lpszBlock, int nMaxLength )
{
	BOOL       fReadStat ;
	COMSTAT    ComStat ;
	DWORD      dwErrorFlags;
	DWORD      dwLength;
	DWORD      dwError;
	char       szError[ 10 ] ;

	// only try to read number of bytes in queue 
	ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
	dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;

	if (dwLength > 0)
	{
		fReadStat = ReadFile(m_hComm, lpszBlock,
		                    dwLength, &dwLength, &m_ReadOS) ;
		if (!fReadStat)
		{
			if (GetLastError() == ERROR_IO_PENDING)
			{
				OutputDebugString("\n\rIO Pending");
				// We have to wait for read to complete. 
				// This function will timeout according to the
				// CommTimeOuts.ReadTotalTimeoutConstant variable
				// Every time it times out, check for port errors
				while(!GetOverlappedResult(m_hComm,&m_ReadOS, &dwLength, TRUE))
				{
					dwError = GetLastError();
					if(dwError == ERROR_IO_INCOMPLETE)
						// normal result if not finished
						continue;
					else
					{
						// an error occurred, try to recover
						wsprintf( szError, "<CE-%u>", dwError ) ;
						MessageBox(NULL,szError,"Read Error",MB_OK);
						ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
						if ((dwErrorFlags > 0) &&m_bDisplayError)
						{
							wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
							MessageBox(NULL,szError,"Read Error",MB_OK);
						}
						break;
					}
						
				}
					
			}
			else
			{
			    // some other error occurred
	
			    dwLength = 0 ;
				ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
				if ((dwErrorFlags > 0) &&m_bDisplayError)
				{
					wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;					
					MessageBox(NULL,szError,"Read Error",MB_OK);
				}
			}
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -