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

📄 pgewavefile.cpp

📁 使ppc屏幕变成黑白的程序
💻 CPP
字号:

// WaveFile.cpp: implementation of the CWaveFile class.
//
//////////////////////////////////////////////////////////////////////
#include "PgeWaveFile.h"
#include "ogginc/TgPlayOgg_use_vorbisfile.h"


#define WF_OFFSET_FORMATTAG			20
#define WF_OFFSET_CHANNELS			22
#define WF_OFFSET_SAMPLESPERSEC		24
#define WF_OFFSET_AVGBYTESPERSEC	28
#define WF_OFFSET_BLOCKALIGN		32
#define WF_OFFSET_BITSPERSAMPLE		34
#define WF_OFFSET_DATASIZE			40
#define WF_OFFSET_DATA				0x24
#define WF_HEADER_SIZE WF_OFFSET_DATA

HANDLE g_hldfSoundThId = NULL;	// 读取文件线程的句柄
DWORD g_dwldfSoundID = 0;		// 线程ID
#define MSG_PGE_SOUND_LOAD WM_USER+0xfff	// 读取下一段的消息

//////////////////////////////////////////////////////////////////////
// LDSOUND函数
// 此函数是读取文件线程的线程函数,实现了分段读取一个声音文件的功能
// 输入参数无意义
// 无返回
//////////////////////////////////////////////////////////////////////
DWORD WINAPI LDSOUND(LPVOID lpparm)	
{
	MSG msg; 
	while(1)
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )		// 是否有消息
		{
			if(GetMessage( &msg, NULL, 0, 0 ) )		// 有消息便取得它
			{
				if (msg.message == MSG_PGE_SOUND_LOAD)	// 是否读取文件的消息
				{
					
					CPGEWaveFile* pWaveFile = (CPGEWaveFile*)msg.lParam;
					if (pWaveFile->m_fpWave == NULL)
					{
						BYTE* btBuf = (BYTE*)pWaveFile->GetWaveData(!pWaveFile->m_iUseMem);
						pWaveFile->DecodeOgg(btBuf, pWaveFile->GetLength(2), (*((int*)msg.wParam)));	
						goto OggOk;
					}
					else
					{	// 如果是Wave文件
						if (pWaveFile->GetLength(2) != PGE_WAVE_MAX_LOAD/2)	
							// 声音缓冲区的长度不对
						{
							char** pBuf = pWaveFile->GetWaveDataPtr(!pWaveFile->m_iUseMem);
							SAFE_DELETE((*pBuf));
							*pBuf = new char[PGE_WAVE_MAX_LOAD/2];
						}

						char* caBuf = pWaveFile->GetWaveData(!pWaveFile->m_iUseMem);	// 取得下一个声音缓冲
						DWORD dwSize = fread(caBuf, 1, pWaveFile->GetLength(2), 
							pWaveFile->m_fpWave);	// 从文件读取并填充到缓冲区
						if (dwSize < pWaveFile->GetLength(2))	// 到了文件尾
						{
							char* buf = new char[dwSize];		// 重新调整缓冲大小rtsp://61.145.118.250/encoder”

							memcpy(buf, caBuf, dwSize);
							char** ppCaBuf = pWaveFile->GetWaveDataPtr(!pWaveFile->m_iUseMem);
							*ppCaBuf = buf;
							SAFE_DELETE(caBuf);
							while(pWaveFile->m_iGetLFlag)	// 确认播放已经开始,因为要修改缓冲的大小,必须等待播放函数取得正确的缓冲大小后再修改
							{
								Sleep(10);
							}
							pWaveFile->m_nLength = dwSize;	// 修改缓冲大小
							(*((int*)msg.wParam))--;	// 播放的循环次数减一
							
							if ((*((int*)msg.wParam)))	// 如果到了文件尾以后还要再次播放
							{
								fseek(pWaveFile->m_fpWave, 0, WF_HEADER_SIZE);	// 文件指针定位到文件头
							}
							else
							{
								pWaveFile->bLoadOver = TRUE;		// 文件读取完毕
							}

						}
					}
OggOk:
					;
				}
				else
				{
					return 0;
				}
			}
		}
		else
		{
			Sleep(30);	// 没有消息,休眠线程
		}
	}
}

//////////////////////////////////////////////////////////////////////
// CPGEWaveFile函数
// CPGEWaveFile构造函数
// 无参数
// 无返回
//////////////////////////////////////////////////////////////////////
CPGEWaveFile::CPGEWaveFile()
{
	m_pbtWaveData[0] = m_pbtWaveData[1] = NULL;
	m_fpWave = NULL;
	m_dwWaveSize = 0;
	m_iUseMem = PGE_SOUND_BUF_1;
	memset(&m_Format, 0, sizeof(m_Format));
	m_iGetLFlag = 0;
	memset(m_fileName, 0, sizeof(m_fileName));
	//if (!g_hldfSoundThId)	// 启动文件读取线程
	//{
	//	g_hldfSoundThId = CreateThread(NULL,0,LDSOUND,NULL,0,&g_dwldfSoundID);			
	//}
}

//////////////////////////////////////////////////////////////////////
// ~CPGEWaveFile函数
// CPGEWaveFile析构函数
// 无参数
// 无返回
//////////////////////////////////////////////////////////////////////
CPGEWaveFile::~CPGEWaveFile()
{

	//PostThreadMessage(g_dwldfSoundID, WM_USER+0xffe, (WPARAM)0, (LPARAM)this);
	SAFE_DELETE(m_pbtWaveData[0]);
	SAFE_DELETE(m_pbtWaveData[1]);
	if (m_fpWave) 
	{
		fclose(m_fpWave);
		m_fpWave = NULL;
	}
}

//////////////////////////////////////////////////////////////////////
// Open函数
// 此函数负责读取声音文件
// 参数 szFileName, 文件名
// 成功返回 PGE_OK,否则 PGE_FAIL
//////////////////////////////////////////////////////////////////////
PGE_RESULT CPGEWaveFile::Open(char* szFileName)
{
	SRESULT;
	if (m_pbtWaveData[PGE_SOUND_BUF_1] != NULL)
		SAFE_DELETE(m_pbtWaveData[PGE_SOUND_BUF_1]);	// 保正缓冲区不会泄露
	if (m_pbtWaveData[PGE_SOUND_BUF_2] != NULL)
		SAFE_DELETE(m_pbtWaveData[PGE_SOUND_BUF_2]);	// 保正缓冲区不会泄露

	strcpy(m_fileName, szFileName);
	char caExtName[4];
	caExtName[3] = 0;
	int iSize = strlen(szFileName) - 1;
	for (int i = 0; i < 3; i++)
	{
		char caTmp = szFileName[iSize - (2-i)];
		if (caTmp < 97) caTmp = caTmp + 32;
		caExtName[i] = caTmp;
	}

	if (0 == strcmp(caExtName, "ogg"))
	{

		if(init_for_ogg_decode(szFileName, &m_pVf)) RET;

		m_nLength = PGE_WAVE_MAX_LOAD / 2;
		m_pbtWaveData[PGE_SOUND_BUF_1] = new BYTE[m_nLength];
		m_pbtWaveData[PGE_SOUND_BUF_2] = new BYTE[m_nLength];
		bLoadOver = FALSE;
		int iLp = 1;
		if (PGEFAILED(DecodeOgg(m_pbtWaveData[PGE_SOUND_BUF_1], m_nLength, iLp))) RET;
		if (PGEFAILED(DecodeOgg(m_pbtWaveData[PGE_SOUND_BUF_2], m_nLength, iLp))) RET;

		RET;
	}


	BYTE aHeader[WF_HEADER_SIZE];	// 文件头

	// 打开文件
	m_fpWave = fopen(szFileName, "rb");
	if (!m_fpWave) {
		RET;
	}

	// 设置声音格式
	fseek(m_fpWave, 0, SEEK_SET);
	fread(aHeader, 1, WF_HEADER_SIZE, m_fpWave);
	m_Format.wFormatTag = *((WORD*) (aHeader + WF_OFFSET_FORMATTAG));
	m_Format.nChannels = *((WORD*) (aHeader + WF_OFFSET_CHANNELS));
	m_Format.nSamplesPerSec = *((DWORD*) (aHeader + WF_OFFSET_SAMPLESPERSEC));
	m_Format.nAvgBytesPerSec = *((DWORD*) (aHeader + WF_OFFSET_AVGBYTESPERSEC));
	m_Format.nBlockAlign = *((WORD*) (aHeader + WF_OFFSET_BLOCKALIGN));
	m_Format.wBitsPerSample = *((WORD*) (aHeader + WF_OFFSET_BITSPERSAMPLE));

	BOOL bData = FALSE;
	int iCount = 0;
	char caBuf[4];
	while(!bData)
	{
		fseek(m_fpWave, WF_HEADER_SIZE + iCount, SEEK_SET);
		fread(caBuf, 1, 4, m_fpWave);
		bData = (*((DWORD*)caBuf) == (*(DWORD*)"data"));
		iCount++;
	}


	// 计算文件长度
	//fseek(m_fpWave, 0, SEEK_END);
	//m_dwWaveSize = ftell(m_fpWave) - WF_HEADER_SIZE;// - 32;

	fread(&m_dwWaveSize, 1, 4, m_fpWave);

	m_nLength = m_dwWaveSize;
	bLoadOver = TRUE;
	if (m_dwWaveSize > PGE_WAVE_MAX_LOAD)	// 是否需要分段读取
	{

		m_nLength = PGE_WAVE_MAX_LOAD / 2;
		m_pbtWaveData[PGE_SOUND_BUF_1] = new BYTE[m_nLength];
		m_pbtWaveData[PGE_SOUND_BUF_2] = new BYTE[m_nLength];
		bLoadOver = FALSE;
	}
	
	if (!m_pbtWaveData[PGE_SOUND_BUF_1])  m_pbtWaveData[PGE_SOUND_BUF_1] = new BYTE[m_nLength];


	// 读取声音内容
	fread(m_pbtWaveData[PGE_SOUND_BUF_1], 1, m_nLength, m_fpWave);
	if (m_pbtWaveData[PGE_SOUND_BUF_2]) fread(m_pbtWaveData[PGE_SOUND_BUF_2], 1, m_nLength, m_fpWave);
	
	if (bLoadOver)		// 一次读取完毕s么?
	{
		fclose(m_fpWave);
		m_fpWave = NULL;
	}
	OKRESULT;
	RET;
}


DWORD CPGEWaveFile::GetLength(int iFlag)
{
	m_iGetLFlag = iFlag;
	return m_nLength;
}

WAVEFORMATEX* CPGEWaveFile::GetWaveFormat() 
{
	return (&m_Format);
}	

char* CPGEWaveFile::GetWaveData(int iBufId)	
{
	if (iBufId < 0)
	{
		return (char*)m_pbtWaveData[m_iUseMem];
	}
	else if (iBufId < 2)
	{
		return (char*)m_pbtWaveData[iBufId];
	}
	else
	{
		return NULL;
	}
}

char** CPGEWaveFile::GetWaveDataPtr(int iBufId)
{
	if (iBufId < 0)
	{
		return (char**)(&m_pbtWaveData[m_iUseMem]);
	}
	else if (iBufId < 2)
	{
		return (char**)(&m_pbtWaveData[iBufId]);
	}
	else
	{
		return NULL;
	}
}


PGE_RESULT CPGEWaveFile::ContinueLoad(BOOL &bLoop)
{
	SRESULT;
	if (bLoadOver) RET;
	m_iUseMem = !m_iUseMem;
	if (PostThreadMessage(g_dwldfSoundID, MSG_PGE_SOUND_LOAD, (WPARAM)&bLoop, (LPARAM)this))
	{
		OKRESULT;
	}

	RET;
}

PGE_RESULT CPGEWaveFile::ReLoad()
{
	bLoadOver = FALSE;
	fseek(m_fpWave, 0, WF_HEADER_SIZE);
	return PGE_OK;
}
//DWORD dwAllBt = 0;
__inline PGE_RESULT CPGEWaveFile::DecodeOgg(BYTE* pBuf, DWORD dwSize, int& iLoop)
{
	SRESULT;
	DWORD dwOutSize = 0;
	int ChannelsCount=0, SamplingRate=0, HoleCount=0, BadLinkCount=0;
	WORD wRealSize = 0;
	while(1)
	{
		
		wRealSize = ogg_decode_at_most_one_vorbis_packet(m_pVf, 
			m_caOggBuf, PGE_OGG_DECODE_SIZE, 16, 
			&ChannelsCount, &SamplingRate, &HoleCount, &BadLinkCount);
		if (wRealSize == 0)	// 到了文件尾
		{
			if (iLoop)
				iLoop--;
			if (iLoop)
			{
				final_ogg_cleanup(m_pVf);
				Open(m_fileName);

			}
			else
			{
				bLoadOver = TRUE;
			}
			break;
		}

		if (dwOutSize+wRealSize >= m_nLength) 
		{
			memcpy(pBuf+dwOutSize, m_caOggBuf, m_nLength-dwOutSize);
//			dwAllBt+=(pgeR(0)+inR(2)-m_nLength);
//			TRACE("忽略字节:%d   全部:%d\r\n", pgeR(0)+inR(2)-m_nLength, dwAllBt);
			
			//while(m_iGetLFlag) NULL;

			//m_nLength = pgeR(0)+inR(2);
			OKRESULT;
			break;
		}
		memcpy(pBuf+dwOutSize, m_caOggBuf, wRealSize);
		dwOutSize += wRealSize;

	}
	if (m_Format.wFormatTag == 0)
	{	
#ifdef _WIN32_WCE
		vorbis_info * pVb = ov_info(static_cast<OggVorbis_File*>(m_pVf), 0);
		ChannelsCount = pVb->channels;
		SamplingRate = pVb->rate;
#endif
		m_Format.wFormatTag = 1;
		m_Format.nChannels = ChannelsCount;
		m_Format.nSamplesPerSec = SamplingRate;
		m_Format.nAvgBytesPerSec = ChannelsCount*SamplingRate*16/8;
		m_Format.nBlockAlign = 16*ChannelsCount/8;
		m_Format.wBitsPerSample = 16;
	}
	
	RET;
}

⌨️ 快捷键说明

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