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

📄 mpafile.cpp

📁 获取mp3信息, Xing header, ID3 tag, APE tag, VBR header
💻 CPP
字号:
#include "stdafx.h"

#include "mpaexception.h"
#include ".\mpafile.h"


/// CMPAFile
//////////////////////////////////////////



CMPAFile::CMPAFile(LPCTSTR szFile)
{
	DWORD dwOffset = 0;
	m_pStream = new CMPAFileStream(szFile);
	m_pTags = new CTags(m_pStream);
	
	// find first valid MPEG frame
	m_pFirstFrame = new CMPAFrame(m_pStream, dwOffset, true, false, false, NULL);

	// check for VBR header
	m_pVBRHeader = m_pFirstFrame->FindVBRHeader();
	
	CalcBytesPerSec();
}

// destructor
CMPAFile::~CMPAFile(void)
{
	if (m_pVBRHeader)
		delete m_pVBRHeader;

	delete m_pFirstFrame;
	delete m_pTags;
	delete m_pStream;

}
#define MAX_EMPTY_FRAMES 25

// try to guess the bitrate of the whole file as good as possible
void CMPAFile::CalcBytesPerSec()
{
	// in case of a VBR header we know the bitrate (if at least the number of frames is known)
	if (m_pVBRHeader && m_pVBRHeader->m_dwFrames)
	{
		DWORD dwBytes = m_pVBRHeader->m_dwBytes;
		// number of bytes can be guessed
		if (!dwBytes)
			m_pVBRHeader->m_dwBytes = GetFileSize();
		
		m_dwBytesPerSec = m_pFirstFrame->m_pHeader->GetBytesPerSecond(m_pVBRHeader->m_dwFrames, dwBytes);
		return;
	}
	
	// otherwise we have to guess it
	
	// go through all frames that have a lower bitrate than 48kbit
	CMPAFrame* pFrame = m_pFirstFrame;
	DWORD dwFrames = 0;
	bool bDeleteFrame = false;
	
	while (pFrame && pFrame->m_pHeader->m_dwBitrate <= 48000)
	{
		pFrame = GetFrame(Next, pFrame, bDeleteFrame);
		if (dwFrames++ > MAX_EMPTY_FRAMES)	
			break;
		bDeleteFrame = true;
	};

	if (!pFrame) {
		pFrame = m_pFirstFrame;
		bDeleteFrame = false;
	}
	m_dwBytesPerSec = pFrame->m_pHeader->GetBytesPerSecond();
	
	if (bDeleteFrame)
		delete pFrame;
	//return true;
}

#define MIN_FRAME_SIZE 24	// MPEG2, LayerIII, 8kbps, 24kHz => Framesize = 24 Bytes

CMPAFrame* CMPAFile::GetFrame(CMPAFile::GetType Type, CMPAFrame* pFrame, bool bDeleteOldFrame, DWORD dwOffset)
{
	CMPAFrame* pNewMPAFrame;
	CMPAHeader* pCompHeader = NULL;
	bool bSubsequentFrame = true;
	bool bReverse = false;
	bool bExactOffset = true;
	
	switch(Type)
	{
		case First:
			dwOffset = GetBegin();
			bSubsequentFrame = true;
			bExactOffset = false;
			break;
		case Last:
			dwOffset = GetEnd() - MIN_FRAME_SIZE;
			bReverse = true;
			bExactOffset = false;
			pCompHeader = m_pFirstFrame->m_pHeader;
			break;
		case Next:
			if (!pFrame)
				return NULL;
			pCompHeader = m_pFirstFrame->m_pHeader;
			dwOffset = pFrame->GetSubsequentHeaderOffset();
			break;
		case Prev:
			if (!pFrame)
				return NULL;
			dwOffset = pFrame->m_dwOffset-MIN_FRAME_SIZE;
			bReverse = true;
			bExactOffset = false;
			pCompHeader = m_pFirstFrame->m_pHeader;
			break;
		case Resync:
			bSubsequentFrame = true;
			bExactOffset = false;
			//pCompHeader = m_pFrame->m_pHeader;
			break;
		default:
			return NULL;
	}

	try
	{
		pNewMPAFrame = new CMPAFrame(m_pStream, dwOffset, bSubsequentFrame, bExactOffset, bReverse, pCompHeader);
		
		
	}
	catch(CMPAException& e)
	{
		// try a complete resync from position dwOffset
		if (Type == Next)
		{
			return GetFrame(Resync, pFrame, bDeleteOldFrame, dwOffset);
		}
		OutputDebugString(e.GetErrorDescription());
		pNewMPAFrame = NULL;
	}
	if (pFrame && bDeleteOldFrame)
		delete pFrame;
	return pNewMPAFrame;
}

⌨️ 快捷键说明

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