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

📄 mpegaudioinfodlg.cpp

📁 获取mp3信息, Xing header, ID3 tag, APE tag, VBR header
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		DWORD dwFileSize = m_pMPAFile->GetFileSize();
		m_strFileInfo.Format(_T("File Size (without Tags): %d Byte (%d KB)\nEstimated Length: %.2d:%.2d"), dwFileSize,
							 dwFileSize / 1024, dwLengthSec / 60, dwLengthSec % 60);

		// current frame is first frame	(need new instance)
		OnBnClickedFirstframe();
	}
	catch(CMPAException& Exc)
	{
		Exc.ShowError();
		m_CtrlPrevFrame.EnableWindow(false);
		m_CtrlNextFrame.EnableWindow(false);
		m_CtrlFirstFrame.EnableWindow(false);
		m_CtrlLastFrame.EnableWindow(false);
		m_CtrlCheckFile.EnableWindow(false);
	}
	UpdateData(false);
}

CString CMPEGAudioInfoDlg::IsVarTrue(bool bVar)
{
	return bVar?_T("Yes"):_T("No");
}

void CMPEGAudioInfoDlg::OnBnClickedNextframe()
{
	CMPAFrame* pFrame;
	if ((pFrame = m_pMPAFile->GetFrame(CMPAFile::Next, m_pFrame)) != NULL)
	{
		m_pFrame = pFrame;
		if (m_dwFrameNo > 0)
			m_dwFrameNo++;
		GetFrameInfo(m_pFrame, m_dwFrameNo);	
	}
}

void CMPEGAudioInfoDlg::OnBnClickedPrevframe()
{
	CMPAFrame* pFrame;
	if ((pFrame = m_pMPAFile->GetFrame(CMPAFile::Prev, m_pFrame)) != NULL)
	{
		m_pFrame = pFrame;
		if (m_dwFrameNo > 1)
			m_dwFrameNo--;
		GetFrameInfo(m_pFrame, m_dwFrameNo);
	}
}

void CMPEGAudioInfoDlg::OnBnClickedFirstframe()
{
	if ((m_pFrame = m_pMPAFile->GetFrame(CMPAFile::First, m_pFrame)) != NULL)
	{
		m_dwFrameNo = 1;
		GetFrameInfo(m_pFrame, m_dwFrameNo);
	}
}

void CMPEGAudioInfoDlg::OnBnClickedLastframe()
{
	if ((m_pFrame = m_pMPAFile->GetFrame(CMPAFile::Last, m_pFrame)) != NULL)
	{
		m_dwFrameNo = 0;
		GetFrameInfo(m_pFrame, m_dwFrameNo);
	}
}

void CMPEGAudioInfoDlg::OnBnClickedCheckfile()
{
	m_strOutput = _T("");

	// go through every frame of the file and look if the next frame is at the computed offset and valid
	CMPAFrame* pCurMPAFrame;
	CMPAFrame* pPrevMPAFrame;

	pCurMPAFrame = m_pMPAFile->GetFrame(CMPAFile::First);
	pPrevMPAFrame = m_pMPAFile->GetFrame(CMPAFile::First);
	if (!pCurMPAFrame || !pPrevMPAFrame)
	{
		m_strOutput = _T("Couldn't find first frame. This is probably no MPEG audio file!");
		return;
	}
	
	DWORD dwPadded = 0, dwUnpadded = 0;
	DWORD dwFrameNo = 0;
	DWORD dwAverBitrate = pCurMPAFrame->m_pHeader->m_dwBitrate;
	bool bVBR = false;
	CString strHelp;

	do
	{
		dwFrameNo++;

		// check CRC
		if (pCurMPAFrame->m_pHeader->m_bCRC)
		{
			if (!pCurMPAFrame->CheckCRC())
			{
				strHelp.Format(_T("Wrong CRC checksum in frame %d\r\n"), dwFrameNo);	
				m_strOutput += strHelp;
			};
		}
		// is it VBR?
		if (pCurMPAFrame->m_pHeader->m_dwBitrate != dwAverBitrate)
		{
			// aver. bitrate += (new bitrate - aver. bitrate / #frames)
			// convert to int (some values can be negative)
			dwAverBitrate += (int)((int)pCurMPAFrame->m_pHeader->m_dwBitrate - (int)dwAverBitrate) / (int)dwFrameNo;
			bVBR = true;
		}

		// even in VBR files these values must not change
		if (pCurMPAFrame->m_pHeader->m_dwSamplesPerSec != pPrevMPAFrame->m_pHeader->m_dwSamplesPerSec)
		{
			CString strNewSamplingRate, strOldSamplingRate;
			strOldSamplingRate.Format(_T("%d Hz"), pPrevMPAFrame->m_pHeader->m_dwSamplesPerSec);
			// new sampling rate
			strNewSamplingRate.Format(_T("%d Hz"), pCurMPAFrame->m_pHeader->m_dwSamplesPerSec);
			InvalidChange( _T("Sampling rate"), dwFrameNo, strOldSamplingRate, strNewSamplingRate);
		}
		if (pCurMPAFrame->m_pHeader->m_Layer != pPrevMPAFrame->m_pHeader->m_Layer)
		{
			InvalidChange( _T("Layer"), dwFrameNo, CMPAHeader::m_szLayers[pPrevMPAFrame->m_pHeader->m_Layer], CMPAHeader::m_szLayers[pCurMPAFrame->m_pHeader->m_Layer] );
		}
		if (pCurMPAFrame->m_pHeader->m_Version != pPrevMPAFrame->m_pHeader->m_Version)
		{
			InvalidChange( _T("Version"), dwFrameNo, CMPAHeader::m_szMPEGVersions[pPrevMPAFrame->m_pHeader->m_Version], CMPAHeader::m_szMPEGVersions[pCurMPAFrame->m_pHeader->m_Version] );
		}
		if (dwFrameNo > 1 && pCurMPAFrame->m_dwOffset != pPrevMPAFrame->GetSubsequentHeaderOffset())
		{
			strHelp.Format( _T("Frame %d header expected at byte %d, but found at byte %d.\r\n")
							  _T("Frame %d (bytes %d-%d) was %d bytes long (expected %d bytes).\r\n\r\n"),
							  dwFrameNo, 
							  pPrevMPAFrame->GetSubsequentHeaderOffset(),
							  pCurMPAFrame->m_dwOffset,	
							  dwFrameNo-1,
							  pPrevMPAFrame->m_dwOffset,
							  pCurMPAFrame->m_dwOffset,
							  pCurMPAFrame->m_dwOffset - pPrevMPAFrame->m_dwOffset,
							  pPrevMPAFrame->m_dwFrameSize );
			m_strOutput += strHelp;
		}
		
		if (pCurMPAFrame->m_pHeader->m_dwPaddingSize > 0)
			dwPadded++;
		else
			dwUnpadded++;

		delete pPrevMPAFrame;
		pPrevMPAFrame = pCurMPAFrame;

	}while ((pCurMPAFrame = m_pMPAFile->GetFrame(CMPAFile::Next, pCurMPAFrame, false)) != NULL);
	
	if (pPrevMPAFrame->GetSubsequentHeaderOffset() > m_pMPAFile->GetEnd())
	{
		strHelp.Format(_T("Last frame truncated.\r\nFrame %d (bytes %d-%d) was %d bytes long (expected %d bytes)\r\n\r\n"), 
			dwFrameNo, pPrevMPAFrame->m_dwOffset, m_pMPAFile->GetEnd(), m_pMPAFile->GetEnd() - pPrevMPAFrame->m_dwOffset, pPrevMPAFrame->m_dwFrameSize);
		m_strOutput += strHelp;
	}
	else if (pPrevMPAFrame->GetSubsequentHeaderOffset() < m_pMPAFile->GetEnd())
	{
		strHelp.Format(_T("Free space or unrecognized Tag after last frame %d (bytes %d-%d).\r\n\r\n"), 
			dwFrameNo, pPrevMPAFrame->m_dwOffset, m_pMPAFile->GetEnd());
		m_strOutput += strHelp;
	}

	if (m_strOutput.IsEmpty())
	{
		m_strOutput += (_T("No errors found in file.\r\n\r\n"));
	}

	m_strOutput += (_T("\r\nSummary:\r\n===============\r\n"));
	strHelp.Format(_T("Total number of frames: %d, unpadded: %d, padded: %d\r\n"), dwFrameNo, dwUnpadded, dwPadded);
	m_strOutput += strHelp;

	DWORD dwLengthSec = pPrevMPAFrame->m_pHeader->GetLengthSecond(dwFrameNo);
	if (bVBR)
		strHelp.Format( _T("File is VBR. Average bitrate is %d kbps.\r\n"), dwAverBitrate/1000);
	else
		strHelp.Format(_T("File is CBR. Bitrate of each frame is %d kbps.\r\n"), dwAverBitrate/1000);
	m_strOutput += strHelp;

	strHelp.Format(_T("Exact length: %.2d:%.2d\r\n"), dwLengthSec / 60, dwLengthSec % 60);
	m_strOutput += strHelp;
	delete pPrevMPAFrame;
	UpdateData(false);
}

void CMPEGAudioInfoDlg::InvalidChange(LPCTSTR szWhat, DWORD dwFrame, LPCTSTR szOldValue, LPCTSTR szNewValue)
{
	CString strHelp;
	strHelp.Format(_T("%s changed in frame %d from %s to %s\r\n"), szWhat, dwFrame, szOldValue, szNewValue);
	m_strOutput += strHelp;
}

void CMPEGAudioInfoDlg::OnBnClickedAbout()
{
	CAboutDlg dlg;
	dlg.DoModal();
}


// this source is not yet used, will be added later to check whole directories instead of single files
/*
#include <shlobj.h>
void CMPEGAudioInfoDlg::OnBnClickedOpendir()
{
	LPMALLOC pMalloc;
	SHGetMalloc(&pMalloc);
	TCHAR szPath[MAX_PATH];

	BROWSEINFO BrowseInfo;
	LPITEMIDLIST pIDList;
	memset(&BrowseInfo, NULL, sizeof(BrowseInfo));
	BrowseInfo.hwndOwner = m_hWnd;
	BrowseInfo.lpszTitle = _T("Select Folder...");
	BrowseInfo.ulFlags = BIF_NEWDIALOGSTYLE|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
	
	BrowseInfo.lpfn = NULL;
	
	pIDList = SHBrowseForFolder(&BrowseInfo);
	SHGetPathFromIDList(pIDList, szPath);

	RecurseFindFile(szPath);	

	pMalloc->Free(pIDList);
	pMalloc->Release();
}

#include "apetag.h"
void CMPEGAudioInfoDlg::RecurseFindFile(LPCTSTR szPath)
{	
	CFileFind Finder;
	CString strSearch;
	strSearch.Format(_T("%s\\*.*"), szPath);
	BOOL bWorking = Finder.FindFile(strSearch);
	while (bWorking)
	{
		bWorking = Finder.FindNextFile();
		if (Finder.IsDots())
			continue;

		// if it's a directory, recursively search it
		if (Finder.IsDirectory())
		{
			RecurseFindFile(Finder.GetFilePath());
		}
		else
		{
			try
			{
				CMPAFile File(Finder.GetFilePath());
				CXINGHeader* pXINGHeader;
			
				// we need runtime type information for the dynamic_cast -> compile this with /GR switch
				// is it a XING header?
				if ((pXINGHeader = dynamic_cast<CXINGHeader*>(File.m_pVBRHeader)) != NULL)
				{
					if (pXINGHeader->m_pLAMETag)
					{
						CString strMsg;
						strMsg.Format(_T("Found LAME Extension in %s"), Finder.GetFilePath());
						AfxMessageBox(strMsg);
					}
				}
			}
			catch(...)
			{
			}
		}
	}
}*/


void CMPEGAudioInfoDlg::OnDropFiles(HDROP hDropInfo)
{
	// get information about dropped files

	// get size of filename of first file
	UINT nBufferSize = ::DragQueryFile(hDropInfo, 0, NULL, 0);
	nBufferSize++;
	LPTSTR szFilename = new TCHAR[nBufferSize];

	// get filename of first file
	::DragQueryFile(hDropInfo, 0, szFilename, nBufferSize);

	LoadMPEGFile(szFilename);

	delete[] szFilename;

	::DragFinish(hDropInfo);

	CDialog::OnDropFiles(hDropInfo);
}

⌨️ 快捷键说明

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