www.pudn.com > hmmPlatform.rar > LargeFileWaveOut.cpp


#include "StdAfx.h" 
#include ".\largefilewaveout.h" 
 
CLargeFileWaveOut::CLargeFileWaveOut(void) 
{ 
	// 设置默认属性 
	this->m_nBufferNums = LARGEWAVEOUT_BUFFER_NUMS; 
	this->m_pNextBuffer = NULL; 
	this->m_pAllocBuffer = NULL; 
	this->m_nBufferNums = 0; 
	this->m_nSamplesPerBlock = LARGEWAVEOUT_SAMPLES_PER_BLOCK; 
	this->m_dwBufferSize = 0; 
} 
 
CLargeFileWaveOut::~CLargeFileWaveOut(void) 
{ 
	this->Stop(); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 打开输出设备,设置回调方式,并分配播放缓冲和读入部分数据 
BOOL CLargeFileWaveOut::Init(WAVEFORMATEX fmt, DWORD hWnd) 
{ 
	// 打开输出设备,设置回调方式 
	BOOL bRet = CFileWaveOut::Init(fmt, hWnd); 
 
	// 读取字节数 
	UINT nRead = 0; 
 
	// 分配缓存区结构 
	if (bRet) 
	{ 
		this->m_pAllocBuffer = new WAVEHDR[this->m_nBufferNums]; 
		this->m_pNextBuffer = this->m_pAllocBuffer; 
 
		// 分配缓冲块 
		if (this->m_pAllocBuffer != NULL) 
		{ 
			for (unsigned int i = 0; i < this->m_nBufferNums; i++) 
			{ 
				this->m_pAllocBuffer[i].lpData = new char[this->m_dwBufferSize]; 
				this->m_pAllocBuffer[i].lpNext = NULL; 
				this->m_pAllocBuffer[i].dwBufferLength = 0; 
 
				if (this->m_pAllocBuffer[i].lpData != NULL &&  
					! this->m_wavFile.IsEOF()) 
				{ 
					// 获取实际读取得byte数 
					nRead = this->m_wavFile.ReadBytes( 
						this->m_pAllocBuffer[i].lpData, this->m_dwBufferSize); 
 
					// 填写缓冲块格式信息 
					this->m_pAllocBuffer[i].dwBufferLength = nRead; 
					this->m_pAllocBuffer[i].dwBytesRecorded = 0; 
					this->m_pAllocBuffer[i].dwFlags = 0; 
					this->m_pAllocBuffer[i].dwLoops = 0; 
					this->m_pAllocBuffer[i].dwUser = 0; 
 
					// 预制缓冲块 
					waveOutPrepareHeader(this->m_hWaveOut,  
						&this->m_pAllocBuffer[i], sizeof(WAVEHDR)); 
				} 
			} 
		} 
	} 
 
	return bRet; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设置缓冲块数量 
void CLargeFileWaveOut::SetBufferNums(UINT nCount) 
{ 
	this->m_nBufferNums = nCount; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 处理WOM_DONE消息,继续播放下一个缓冲块 
LRESULT CLargeFileWaveOut::OnDone(DWORD dwParam) 
{ 
	WAVEHDR* pTempHdr = (WAVEHDR*) dwParam;		// 播放完的缓冲块 
	UINT nRead = 0; 
 
	// 已播放的缓冲块标记长度为0,用于标记已经播放 
	pTempHdr->dwBufferLength = 0; 
 
	// 确定待播放的缓冲块,类似使用循环队列 
	if (this->m_pNextBuffer - this->m_pAllocBuffer >= this->m_nBufferNums) 
	{ 
		this->m_pNextBuffer = this->m_pAllocBuffer; 
	} 
 
	// 若要播放的缓冲块未播放过,则播放此缓冲块 
	if (this->m_pNextBuffer->dwBufferLength > 0) 
	{ 
		waveOutWrite(this->m_hWaveOut, this->m_pNextBuffer, sizeof(WAVEHDR)); 
		this->m_pNextBuffer ++; 
 
		// 若文件未读取完毕,从文件载入下一个缓冲块,装入已播放缓冲块中 
		if (! this->m_wavFile.IsEOF()) 
		{ 
			nRead = this->m_wavFile.ReadBytes(pTempHdr->lpData, this->m_dwBufferSize); 
 
			// 填写缓冲块信息 
			pTempHdr->dwBufferLength = nRead; 
			pTempHdr->dwBytesRecorded = 0; 
			pTempHdr->dwFlags = 0; 
			pTempHdr->dwLoops = 0; 
			pTempHdr->dwUser = 0; 
		} 
	} 
	// 所有缓冲块都已经播放完毕,停止播放 
	else 
	{ 
		this->Stop(); 
	} 
 
	return 0; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定缓冲块大小 
void CLargeFileWaveOut::SetSamplesPerBlock(UINT nSamplesCount) 
{ 
	this->m_nSamplesPerBlock = nSamplesCount; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 清除缓冲区,初始化数据 
void CLargeFileWaveOut::Dispose() 
{ 
	// 释放播放文件分配的缓存 
	if (this->m_pAllocBuffer != NULL) 
	{ 
		// 释放所有缓冲块 
		for (unsigned int i = 0; i < this->m_nBufferNums; i++) 
		{ 
			this->m_pNextBuffer = &this->m_pAllocBuffer[i]; 
 
			if (this->m_pNextBuffer->lpData != NULL) 
			{ 
				delete[] this->m_pNextBuffer->lpData; 
			} 
		} 
 
		// 删除缓冲结构 
		delete[] this->m_pAllocBuffer; 
	} 
 
	this->m_pAllocBuffer = NULL; 
	this->m_pNextBuffer = NULL; 
 
	// 重置CWaveOut数据 
	CWaveOut::Dispose(); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 开始播放音频逻数据,发送第一个缓冲块 
void CLargeFileWaveOut::Start() 
{ 
	if (this->m_pAllocBuffer != NULL) 
	{ 
		CWaveOut::Start(); 
 
		// 发送第一个缓冲块 
		this->m_pNextBuffer = this->m_pAllocBuffer + 1; 
		waveOutWrite(this->m_hWaveOut, this->m_pAllocBuffer, sizeof(WAVEHDR)); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 停止播放,关闭输出设备, UnPrepare所用到的缓冲块 
void CLargeFileWaveOut::Stop() 
{ 
	// 停止播放 
	CWaveOut::Stop(); 
 
	// UnPrepare所有缓冲块 
	for (unsigned int i = 0; i < this->m_nBufferNums; i++) 
	{ 
		this->m_pNextBuffer = &this->m_pAllocBuffer[i]; 
		waveOutUnprepareHeader( 
			this->m_hWaveOut, this->m_pNextBuffer, sizeof(WAVEHDR)); 
	} 
 
	// 关闭输出设备 
	CWaveOut::CloseDev(); 
 
	// 清除缓冲区,初始化数据 
	this->Dispose(); 
}