gusucode.com > 基于VC++的局域网视频聊天系统源码程序 > 基于VC++的局域网视频聊天系统源码程序/code/ChatClient/AudioRec.cpp

    // AudioRec.cpp: implementation of the CAudioRec class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ChatClientDlg.h"
#include "AudioRec.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE(CAudioRec, CWinThread)

BEGIN_MESSAGE_MAP(CAudioRec,CWinThread)
	ON_THREAD_MESSAGE(MM_WIM_DATA, OnSoundData)
	ON_THREAD_MESSAGE(WM_RECORDSOUND_STARTRECORDING,OnStartRecording)
	ON_THREAD_MESSAGE(WM_RECORDSOUND_STOPRECORDING,OnStopRecording)
	ON_THREAD_MESSAGE(WM_RECORDSOUND_ENDTHREAD,OnEndThread)
END_MESSAGE_MAP()

CAudioRec::CAudioRec()
{

}

CAudioRec::~CAudioRec()
{
	//	TRACE("CAudioRec::~CAudioRec\n");
	if(!isallocated)	return;

	for(int i=0;i<MAXRECBUFFER;i++)
	{
		if(rechead[i])
		{
			if(rechead[i]->lpData )
				delete [](rechead[i]->lpData);
			delete rechead[i];
		}
	}
}

CAudioRec::CAudioRec(CDialog *dialog)
{
	//	TRACE("CAudioRec::CAudioRec(CDialog *dialog)\n");
	pDlg=dialog;
	
	recording=FALSE;
	isallocated=0;

	PreCreateHeader();

	//Setting WAVEFORMATEX  structure for the audio input
	memset(&m_WaveFormatEx,0x00,sizeof(m_WaveFormatEx));
	m_WaveFormatEx.wFormatTag		=	WAVE_FORMAT_PCM;
	m_WaveFormatEx.nChannels		=	1;
	m_WaveFormatEx.wBitsPerSample	=	16;
	m_WaveFormatEx.cbSize			=	0;
	m_WaveFormatEx.nSamplesPerSec	=	SAMPLEPSEC;  //22.05 KHz
	m_WaveFormatEx.nBlockAlign		=	m_WaveFormatEx.wBitsPerSample/8;
	m_WaveFormatEx.nAvgBytesPerSec	=	m_WaveFormatEx.nBlockAlign * m_WaveFormatEx.nSamplesPerSec;

}

BOOL CAudioRec::InitInstance()
{
	return TRUE;
}


int CAudioRec::ExitInstance()
{
	return CWinThread::ExitInstance();
}

void CAudioRec::PreCreateHeader()
{
	for(int i=0;i<MAXRECBUFFER;i++)
		rechead[i]=CreateWaveHeader();
	isallocated=1;
}

LRESULT CAudioRec::OnStartRecording(WPARAM wp, LPARAM lp)
{
	if(recording)	return FALSE;
	
	//打开录音设备
	MMRESULT mmReturn = 
		::waveInOpen( &m_hRecord, WAVE_MAPPER,
			&m_WaveFormatEx, ::GetCurrentThreadId(), 0, CALLBACK_THREAD);
	if(mmReturn!=MMSYSERR_NOERROR )		return FALSE;

	if(mmReturn==MMSYSERR_NOERROR )
	{
		for(int i=0; i < MAXRECBUFFER ; i++)
		{
			//为录音设备准备缓存
			mmReturn = ::waveInPrepareHeader(m_hRecord,rechead[i], sizeof(WAVEHDR));
			//给输入设备增加一个缓存
			mmReturn = ::waveInAddBuffer(m_hRecord, rechead[i], sizeof(WAVEHDR));
		}
		//开始录音
		mmReturn = ::waveInStart(m_hRecord);
		if(mmReturn==MMSYSERR_NOERROR ) 	recording=TRUE;
	}
	return TRUE;
}

LRESULT CAudioRec::OnStopRecording(WPARAM wp, LPARAM lp)
{
	MMRESULT mmReturn = 0;
	
	if(!recording)		return FALSE;

	mmReturn = ::waveInStop(m_hRecord);
	recording = FALSE;		
//	if(!mmReturn)
	mmReturn = ::waveInReset(m_hRecord);  
	Sleep(500); 
	//if(!mmReturn)		
	mmReturn = ::waveInClose(m_hRecord);
	return mmReturn;
}

LRESULT CAudioRec::OnSoundData(WPARAM wParam, LPARAM lParam)
{
	int clen=1;
	if(recording==FALSE)	return FALSE;

	LPWAVEHDR lpHdr = (LPWAVEHDR) lParam;
	
	if(lpHdr->dwBytesRecorded==0 || lpHdr==NULL)	return ERROR_SUCCESS;
		
	::waveInUnprepareHeader(m_hRecord, lpHdr, sizeof(WAVEHDR));  //清除缓存

	// Send recorded audio to remote host...
	if(lpHdr->lpData!=NULL )
	{
		( (CChatClientDlg*) pDlg )->m_G729aCompress .Compress  (lpHdr->lpData,lpHdr->dwBytesRecorded,((CChatClientDlg*) pDlg )->m_AComped,&clen);
		if(clen>0)
		{
			((CChatClientDlg*) pDlg )->daudio.SendAudioData((unsigned char *)(((CChatClientDlg*) pDlg )->m_AComped),clen);
			((CChatClientDlg*) pDlg )->m_ABytesSent +=clen;
			((CChatClientDlg*) pDlg )->m_AFrames  ++;
		}
	}

	if(recording)
	{	//Reuse the old buffer
		::waveInPrepareHeader(m_hRecord,lpHdr, sizeof(WAVEHDR)); //准备缓存
		::waveInAddBuffer(m_hRecord, lpHdr, sizeof(WAVEHDR));   //给设备增加一个缓存
	}
	return ERROR_SUCCESS;
}

LRESULT CAudioRec::OnEndThread(WPARAM wp, LPARAM lp)
{
	if(recording)	OnStopRecording(0,0);

	::PostQuitMessage(0);
	return TRUE;
}



LPWAVEHDR CAudioRec::CreateWaveHeader()
{
	LPWAVEHDR lpHdr = new WAVEHDR;
	if(lpHdr==NULL)		return NULL;
	
	ZeroMemory(lpHdr, sizeof(WAVEHDR));
	char* lpByte = new char[RECBUFFER];
	
	if(lpByte==NULL)	return NULL;

	lpHdr->lpData =  lpByte;
	lpHdr->dwBufferLength =RECBUFFER;
	return lpHdr;
}