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

    // AudioPlay.cpp: implementation of the CAudioPlay class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AudioPlay.h"

IMPLEMENT_DYNCREATE(CAudioPlay, CWinThread)

BEGIN_MESSAGE_MAP(CAudioPlay, CWinThread)
	ON_THREAD_MESSAGE(WM_PLAYSOUND_STARTPLAYING, OnStartPlaying)
	ON_THREAD_MESSAGE(WM_PLAYSOUND_STOPPLAYING, OnStopPlaying)
	ON_THREAD_MESSAGE(WM_PLAYSOUND_PLAYBLOCK, OnWriteSoundData)
	ON_THREAD_MESSAGE(MM_WOM_DONE, OnEndPlaySoundData)
	ON_THREAD_MESSAGE(WM_PLAYSOUND_ENDTHREAD,OnEndThread)
END_MESSAGE_MAP()

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

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

CAudioPlay::CAudioPlay()
{

}

CAudioPlay::~CAudioPlay()
{

}

CAudioPlay::CAudioPlay(CDialog *dialog)
{
	pDlg = dialog;
	
	
	memset(&m_WaveFormatEx,0x00,sizeof(m_WaveFormatEx));
	m_WaveFormatEx.wFormatTag		= WAVE_FORMAT_PCM;
	m_WaveFormatEx.nChannels		= 1;
	m_WaveFormatEx.wBitsPerSample	= 16;
	m_WaveFormatEx.nSamplesPerSec	= SAMPLEPSEC;
	m_WaveFormatEx.nBlockAlign		= m_WaveFormatEx.wBitsPerSample/8;
	m_WaveFormatEx.nAvgBytesPerSec	= m_WaveFormatEx.nBlockAlign*m_WaveFormatEx.nSamplesPerSec ;
	m_WaveFormatEx.cbSize			= 0;
	Playing = FALSE;

}

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

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

LRESULT CAudioPlay::OnStartPlaying(WPARAM wParam, LPARAM lParam)
{
//	TRACE("CAudioPlay::OnStartPlaying\n");
	MMRESULT mmReturn = 0;

	if(Playing)	return FALSE;

	//打开回放设备
	mmReturn = ::waveOutOpen( &m_hPlay, WAVE_MAPPER,&m_WaveFormatEx, ::GetCurrentThreadId(), 0, CALLBACK_THREAD);
	if(!mmReturn )		
	{	
		Playing = TRUE;
		DWORD volume=0xFFFFFFFF;
		waveOutSetVolume(m_hPlay,volume);
	}
	m_Count=0;
	return TRUE;
}

LRESULT CAudioPlay::OnStopPlaying(WPARAM wParam, LPARAM lParam)
{
//	TRACE("CAudioPlay::OnStopPlaying\n");
	MMRESULT mmReturn = 0;

	if(Playing==FALSE)		return FALSE;

//	TRACE("CAudioPlay::OnStopPlaying, %d frame audio not played\n",m_Count);
	mmReturn = ::waveOutReset(m_hPlay);
		
	if(mmReturn != MMSYSERR_NOERROR)
	{
		Playing = FALSE;
		m_Count=0;
		Sleep(500);
	}
	mmReturn = ::waveOutClose(m_hPlay);  //关闭回放设备

	return mmReturn;
}

LRESULT CAudioPlay::OnEndPlaySoundData(WPARAM wParam, LPARAM lParam)
{
//	TRACE("CAudioPlay::OnEndPlaySoundData\n");
	
	LPWAVEHDR lpHdr = (LPWAVEHDR) lParam;
	
	if(lpHdr)		
	{
		::waveOutUnprepareHeader(m_hPlay, lpHdr, sizeof(WAVEHDR));
		if(lpHdr->lpData != NULL){
			//delete []lpHdr->lpData;
			//lpHdr->lpData = NULL;
		}
        if(lpHdr != NULL){
			delete lpHdr;
			lpHdr = NULL;
		}
		m_Count--;
//		TRACE("CAudioPlay::OnEndPlaySoundData, %d audio frame to be played\n",m_Count);
	}
	return ERROR_SUCCESS;
}

LRESULT CAudioPlay::OnWriteSoundData(WPARAM wParam, LPARAM lParam)
{
//	TRACE("CAudioPlay::OnWriteSoundData\n");
	MMRESULT mmResult = FALSE;
	char *p=NULL;
	int length=(int) wParam;

	if(Playing==FALSE)	return FALSE;
	
	if(length<=0)	return FALSE;

	WAVEHDR *lpHdr=new WAVEHDR;
	if(!lpHdr)	return FALSE;
	p=new char [length];
	if(!p)	
	{
		delete lpHdr;
		return FALSE;
	}
	ZeroMemory(lpHdr,sizeof(WAVEHDR));
	ZeroMemory(p,length);
	CopyMemory(p,(char*)lParam,length);
	lpHdr->lpData=p;
	lpHdr->dwBufferLength = length;

	mmResult = ::waveOutPrepareHeader(m_hPlay, lpHdr, sizeof(WAVEHDR));   //为回放设备准备内存块

	if(mmResult)
	{
		delete lpHdr;delete p;
		return mmResult;
	}
	
	mmResult = ::waveOutWrite(m_hPlay, lpHdr, sizeof(WAVEHDR));   //写数据(放音)
	if(mmResult)
	{
		delete lpHdr;delete p;
		return mmResult;
	}
	m_Count++;
	return MMSYSERR_NOERROR;
}


LRESULT CAudioPlay::OnEndThread(WPARAM wParam, LPARAM lParam)   //关闭线程
{
//	TRACE("CAudioPlay::OnEndThread\n");

	if(Playing==TRUE)	OnStopPlaying(0,0);

	::PostQuitMessage(0);
	return TRUE;
}